#include "pika_hal_cirQueue.h"
//类型为void*的队列
#if 1
pika_hal_cirQueue* pika_hal_cirQueue_create(size_t capacity) {
    pika_hal_cirQueue* cb = (pika_hal_cirQueue*)pikaMalloc(sizeof(pika_hal_cirQueue));
    if (NULL == cb) {
        return NULL;
    }
    cb->head = 0;
    cb->tail = 0;
    cb->count = 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_init(&cb->mutex);
#endif
    cb->capacity = capacity;
    cb->buffer = (void**)pikaMalloc(capacity * sizeof(void*));  // 分配足够的空间来存储指针
    if (NULL == cb->buffer) {
        pikaFree(cb, sizeof(pika_hal_cirQueue));
        return NULL;
    }
    return cb;
}

size_t pika_hal_cirQueue_appendTail(pika_hal_cirQueue* cb, void* value) {
    size_t ret = 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    if (cb->count == cb->capacity) {
        ret = -1;
        goto __exit;
    }

    cb->buffer[cb->tail] = value;
    cb->tail = (cb->tail + 1) % cb->capacity;
    cb->count++;
__exit:
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif
    return ret;
}

//以下待测试
size_t pika_hal_cirQueue_appendHead(pika_hal_cirQueue* cb, void* value) {
    size_t ret = 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    if (cb->count == cb->capacity) {
        ret = -1;  // 队列已满
        goto __exit;
    }

    // 更新 head 指针前的位置，然后更新 head
    cb->head = (cb->head - 1 + cb->capacity) % cb->capacity;
    cb->buffer[cb->head] = value;
    cb->count++;
__exit:
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif
    return ret;
}

size_t pika_hal_cirQueue_popHead(pika_hal_cirQueue* cb, void** value) {
    size_t ret = 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    if (cb->count == 0) {
        ret = -1;
        goto __exit;
    }

    *value = cb->buffer[cb->head];
    cb->head = (cb->head + 1) % cb->capacity;
    cb->count--;
__exit:
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif
    return ret;
}




size_t pika_hal_cirQueue_popTail(pika_hal_cirQueue* cb, void** value) {
    size_t ret = 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    if (cb->count == 0) {
        ret = -1;  // 队列为空
        goto __exit;
    }

    *value = cb->buffer[cb->tail - 1];
    cb->tail = (cb->tail - 1 + cb->capacity) % cb->capacity;
    cb->count--;
__exit:
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif
    return ret;
}


size_t pika_hal_peekHead(pika_hal_cirQueue* cb, void** value) {
    if (cb->count == 0) {
        return -1;
    }

#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    *value = cb->buffer[cb->head];
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif

    return 0;
}

size_t pika_hal_peekTail(pika_hal_cirQueue* cb, void** value) {
    if (cb->count == 0) {
        return -1;  // 队列为空
    }

#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    *value = cb->buffer[(cb->tail - 1 + cb->capacity) % cb->capacity];
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif

    return 0;
}


size_t pika_hal_cirQueue_deinit(pika_hal_cirQueue* cb) {
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    pikaFree(cb->buffer, cb->capacity * sizeof(void*));  // 释放指针数组
    cb->buffer = NULL;
    cb->head = 0;
    cb->tail = 0;
    cb->count = 0;
    cb->capacity = 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_destroy(&cb->mutex);
#endif
    pikaFree(cb, sizeof(pika_hal_cirQueue));
    return 0;
}

size_t pika_hal_cirQueue_getCount(pika_hal_cirQueue* cb) {
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    size_t count = cb->count;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif
    return count;
}

size_t pika_hal_cirQueue_isEmpty(pika_hal_cirQueue* cb) {
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    size_t res = cb->count == 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif
    return res;
}

size_t pika_hal_cirQueue_isFull(pika_hal_cirQueue* cb) {
    size_t res = cb->count == cb->capacity;
    return res;
}
#endif  //类型为void*的队列


//类型为char的队列
#if 1

// 创建一个新的循环字符队列
pika_hal_cirQueueByte* pika_hal_cirQueueByte_create(size_t capacity) {
    pika_hal_cirQueueByte* cb = (pika_hal_cirQueueByte*)pikaMalloc(sizeof(pika_hal_cirQueueByte));
    if (NULL == cb) {
        return NULL;
    }
    cb->head = 0;
    cb->tail = 0;
    cb->count = 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_init(&cb->mutex);
#endif
    cb->capacity = capacity;
    cb->buffer = (char*)pikaMalloc(capacity * sizeof(char));  // 分配足够的空间来存储字符
    if (NULL == cb->buffer) {
        pikaFree(cb, sizeof(pika_hal_cirQueueByte));
        return NULL;
    }
    return cb;
}

// 向队列尾部添加一个字符
size_t pika_hal_cirQueueByte_appendTail(pika_hal_cirQueueByte* cb, char value) {
    size_t ret = 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    if (cb->count == cb->capacity) {
        ret = -1;
        goto __exit;
    }

    cb->buffer[cb->tail] = value;
    cb->tail = (cb->tail + 1) % cb->capacity;
    cb->count++;
__exit:
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif
    return ret;
}

// 从队列头部移除一个字符
size_t pika_hal_cirQueueByte_popHead(pika_hal_cirQueueByte* cb, char* value) {
    size_t ret = 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    if (cb->count == 0) {
        ret = -1;
        goto __exit;
    }

    *value = cb->buffer[cb->head];
    cb->head = (cb->head + 1) % cb->capacity;
    cb->count--;
__exit:
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif
    return ret;
}

size_t pika_hal_cirQueueByte_appendHead(pika_hal_cirQueueByte* cb, char value) {
    size_t ret = 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    if (cb->count == cb->capacity) {
        ret = -1;  // 队列已满
        goto __exit;
    }

    // 更新 head 指针前的位置，然后更新 head
    cb->head = (cb->head - 1 + cb->capacity) % cb->capacity;
    cb->buffer[cb->head] = value;
    cb->count++;
__exit:
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif
    return ret;
}

size_t pika_hal_cirQueueByte_popTail(pika_hal_cirQueueByte* cb, char* value) {
    size_t ret = 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    if (cb->count == 0) {
        ret = -1;  // 队列为空
        goto __exit;
    }

    *value = cb->buffer[(cb->tail - 1 + cb->capacity) % cb->capacity];
    cb->tail = (cb->tail - 1 + cb->capacity) % cb->capacity;
    cb->count--;
__exit:
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif
    return ret;
}

size_t pika_hal_cirQueueByte_peekHead(pika_hal_cirQueueByte* cb, char* value) {
    if (cb->count == 0) {
        return -1;  // 队列为空
    }

#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    *value = cb->buffer[cb->head];
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif

    return 0;
}

size_t pika_hal_cirQueueByte_peekTail(pika_hal_cirQueueByte* cb, char* value) {
    if (cb->count == 0) {
        return -1;  // 队列为空
    }

#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    *value = cb->buffer[(cb->tail - 1 + cb->capacity) % cb->capacity];
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif

    return 0;
}


// 销毁队列并释放相关资源
size_t pika_hal_cirQueueByte_deinit(pika_hal_cirQueueByte* cb) {
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    pikaFree(cb->buffer, cb->capacity * sizeof(char));  // 释放字符数组
    cb->buffer = NULL;
    cb->head = 0;
    cb->tail = 0;
    cb->count = 0;
    cb->capacity = 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_destroy(&cb->mutex);
#endif
    pikaFree(cb, sizeof(pika_hal_cirQueueByte));
    return 0;
}

// 获取队列中的元素数量
size_t pika_hal_cirQueueByte_getCount(pika_hal_cirQueueByte* cb) {
    size_t count;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    count = cb->count;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif
    return count;
}

// 检查队列是否为空
size_t pika_hal_cirQueueByte_isEmpty(pika_hal_cirQueueByte* cb) {
    size_t res;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_acquire(&cb->mutex, pika_true, -1);
#endif
    res = cb->count == 0;
#if PIKA_HAL_CIRCULAR_QUEUE_MUTEX_ENABLE
    pika_platform_thread_lock_release(&cb->mutex);
#endif
    return res;
}

// 检查队列是否已满
size_t pika_hal_cirQueueByte_isFull(pika_hal_cirQueueByte* cb) {
    size_t res = cb->count == cb->capacity;
    return res;
}
#endif  //类型为char的队列
